# Maps.py: maps module
# 22/06/09
# Copyright(c) 2009 Victor Freire e Cassio Espindola. All rights reserved.
# Python 2.6.2

import pygame
import os
import string
import copy
import Shared
import Renderer
import Gameobjects
import Defines


class MapsClass:
    def __init__(self):
        self.DEFAULT_PATH = os.path.join(os.curdir, "data", "maps")
        self.maps = {}
        self.objects = {}
        self.maps_start_pos = {}
        self.world = None
        self.world_bounds = (0, 0)
    
    
    def load_maps(self):
        for roots, dirs, files in os.walk(self.DEFAULT_PATH):
            for map_name in files:
                if map_name[-3:] == 'dat':
                    if map_name[:3] == 'map':
                        # Load the map
                        try:
                            world = []
                            f = open(os.path.join(self.DEFAULT_PATH,map_name),'r')
                            content = f.readlines()
                            for line in content:
                                line = line.strip()
                                line = list(line)
                                world.append(line)
                            
                            found = False
                            for y in xrange(len(world)):
                                for x in xrange(len(world[0])):
                                    if world[y][x] == 'P':
                                        world[y][x] = '0'
                                        self.maps_start_pos[map_name[:-4]] = (x*Defines.CUBE_SIZE+30, y*Defines.CUBE_SIZE+30)
                                        found = True
                                        break
                                if found:
                                    break
                            
                            self.maps[map_name[:-4]] = copy.deepcopy(world)
                            f.close()
                        except:
                            print "Unable to open the map file - %s" % f
                    
                    elif map_name[:3] == 'mon':
                        # Loads the monsters for this map
                        try:
                            monsters = []
                            f = open(os.path.join(self.DEFAULT_PATH, map_name),'r')
                            content = f.readlines()
                            for line in content:
                                line = line.strip()
                                if not line or line.isspace(): continue
                                fields = line.split('|')
                                
                                if len(fields) != 3:
                                    print "Invalid monsters file - err 0- %s" % f
                                    continue
                                
                                template = fields[0]
                                pos1 = [int(i) for i in fields[1].split('-')]
                                if not len(pos1) == 2: print "Invalid monsters file - err 1 - %s" % f
                                
                                if fields[2]:
                                    pos2 = [int(i) for i in fields[2].split('-')]
                                    if not len(pos2) == 2: print "Invalid monsters file - err 2 - %s" % f
                                else:
                                    pos2 = None
                                
                                monsters.append(Gameobjects.Enemy(template, pos1, pos2))
                            self.objects[('map' + map_name[-5])] = copy.deepcopy(monsters)
                            f.close()
                        except:
                            print "Unable to open the monsters file - %s" % f
    
    def get_start_pos(self, map_name):
        try:
            return self.maps_start_pos[map_name]
        except:
            return (Defines.MAP_START_POS_X, Defines.MAP_START_POS_Y)
    
    
    def get_map(self, map_name):
        try:
            return self.maps[map_name]
        except:
            print "Fatal Error on loading map - %s" % map_name #unrecoverable error
            raise SystemExit
        
    
    def get_objects(self, map_name):
        try:
            return self.objects[map_name]
        except:
            print "Fatal Error on loading map objects for map - %s" % map_name #no need to crash ...
            return []
            #raise SystemExit
            
    
       
    def set_current_map(self, map_name):
        ''' Sets the map to be played. '''
        if not self.maps: self.load_maps()
        self.world = self.get_map(map_name)
        self.world_bounds = (len(self.world[0]), len(self.world))
    
        
    def wall_onG(self, gridpos):
        ''' Checks if there is a wall on given grid coordinates. '''
        return self.world[gridpos[1]][gridpos[0]] != '0'
        
            
    def wall_onU(self, pos):
        ''' Checks if there is a wall on given unit coordinates. '''
        gridpos = Renderer.togridF(pos[0], pos[1])
        return self.world[gridpos[1]][gridpos[0]] != '0'
    
    def is_valid_unit(self, unitpos):
        ''' Is the unit coordinates passed valid? '''
        return self.is_valid_grid(Renderer.togridF(unitpos[0], unitpos[1]))
    
    def is_valid_grid(self, gridpos):
        ''' Is the grid passed valid? '''
        return 0 <= gridpos[0] < self.world_bounds[0] and 0 <= gridpos[1] < self.world_bounds[1]
                

Maps = MapsClass()


